{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. 函数\n",
    "python中的函数很简单，用def定义一个函数，函数体有四个空格作为缩进，在函数名后面加一对儿括号就可以调用该函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def test():\n",
    "    print(\"test\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "参数直接写在括号里面就行，不需要声明它的类型，返回值用return返回"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def sum_even(lista):\n",
    "    '''\n",
    "    求一个列表中偶数元素之和\n",
    "    '''\n",
    "    s = 0\n",
    "    for i in lista:\n",
    "        if i % 2 == 0:\n",
    "            s += i\n",
    "    return s"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum_even([1,2,3,4,5,6,7,8,9,10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的函数，可以返回多个值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def sum_odd_even(lista):\n",
    "    '''\n",
    "    求一个列表中奇数之和和偶数之和\n",
    "    '''\n",
    "    s_odd = 0\n",
    "    s_even = 0\n",
    "    for i in lista:\n",
    "        if i % 2 == 0:\n",
    "            s_even += i\n",
    "        else:\n",
    "            s_odd += i\n",
    "    return s_odd, s_even"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum_odd_even([1,2,3,4,5,6,7,8,9,10])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "事实上，返回的还是一个值，并不是两个值，返回的是一个tuple"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在python中定义函数的时候，由于不需要定义形参的类型，所以很多时候函数的参数是很灵活的，像上面的函数，我们不光可以传入list，还可以传入tuple和set，或是其他的可迭代类型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum_odd_even((1,2,3,4,5,6,7,8,9,10)) # 传入一个tuple"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum_odd_even({1,2,3,4,5,6,7,8,9,10}) # 传入一个set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sum_odd_even({1:\"1\", 2:\"2\"}) # 传入一个dict"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，如果传入的参数是一个可变类型的变量，如果函数的功能对传入的这个可变类型的变量进行了修改，那么原来传入的这个值就会被改变"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def modify(lista):\n",
    "    '''\n",
    "    清空lista\n",
    "    '''\n",
    "    lista.clear()\n",
    "    print('clear list!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = [1,2,3,4]\n",
    "modify(a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，此时的列表已经变成空的了，但是如果我们传入的是一个元组呢"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "modify((1,2,3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，元组是没有clear这个方法的，所以程序报了错。可以看到，**元组往往比列表更安全！**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 默认参数"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的函数在定义时，可以选择默认参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def test(num = 0):\n",
    "    '''\n",
    "    打印num这个变量，如果没有num传入，num默认为0\n",
    "    '''\n",
    "    print(num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test(100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "只要在定义的时候，指明这个默认变量的值即可。  \n",
    "需要注意一点，如果定义的这个函数有很多参数，那么默认参数，一定要写在非默认参数的后面"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def test(num = 0, n):\n",
    "    print(num + n)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "上面的定义是有问题的，默认参数后面跟了非默认参数，应该改成下面的样子"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def test(n, num = 0):\n",
    "    print(n + num)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test(1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 匿名函数\n",
    "和其他大多数语言一样，Python也提供了匿名函数的功能，语法如下：\n",
    "```python\n",
    "lambda param1, param2, ... : f(param1, param2, ...)\n",
    "```\n",
    "比如说定义一个a+b的函数：\n",
    "```python\n",
    "foo = lambda a, b : a + b\n",
    "print(foo(2,3))\n",
    "```\n",
    "定义一个sin(x)+cos(x)的函数：\n",
    "```python\n",
    "import math\n",
    "sin_cos = lambda x: math.sin(x) + math.cos(x)\n",
    "print(sin_cos(1.5))\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print((lambda x : x**2+x)(10)) # x^2+x\n",
    "foo = lambda f, x: f(x) + f(2*x)\n",
    "print(foo(10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 判断"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的if else没有花括号，使用4个空格作为缩进，具有相同缩进的代码块为一个整体。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if 2 > 1:\n",
    "    print(\"2 > 1\")\n",
    "    print(\"haha\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "if 2 < 1:\n",
    "    print(\"2 > 1\")\n",
    "    print(\"haha\")\n",
    "else:\n",
    "    print(\"2 < 1\")\n",
    "    print(\"heihei\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用if elif else可以实现多种条件的判断，无需使用if else嵌套"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 1\n",
    "if x<-1:\n",
    "    y = 2-x\n",
    "elif 1 <= x <= 1/2:\n",
    "    y = -3 * x\n",
    "else:\n",
    "    y = x - 2\n",
    "print(y)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 循环"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的循环有for和while"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# while\n",
    "while与其他语言的while差不多，只要while后面的条件满足，就一直执行下去，和if语句类似，具有相同缩进的代码块会被同时执行"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "index = 0\n",
    "s = 0\n",
    "while index <= 100:\n",
    "    s += index\n",
    "    index += 1\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# for"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的for与c中的for有很大区别，python中的for循环的形式是：  \n",
    "for i in iterable:  \n",
    "其中，每循环一次，i都会分别表示可迭代对象iterable中的每一项"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [1,2,3,4,5,6,7]:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [[1,2,3], [4,5,6], [7,8,9]]:\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in [[1,2,3], [4,5,6], [7,8,9]]:\n",
    "    for j in i:\n",
    "        print(j, end = ' ')\n",
    "    print()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中提供了一个range函数，这个函数接受3个参数，这三个参数与list的切片接受的参数差不多"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "range(5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(5):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "range(2, 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(2, 5):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "range(1, 11, 2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(1, 11, 2):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "第一个参数代表起始值（不指定的时候默认为0）；第二值是必须传入的参数，代表终点，但是该值不会出现在迭代器中，迭代器中的最后一个数为它前面的一个数；第三个值为步长，可以缺省，默认为1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test1\n",
    "使用while循环和for循环遍历下面的列表numbers，并打印出奇数的个数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "import random\n",
    "\n",
    "numbers = [random.randint(-100, 100) for i in range(random.randint(20, 100))]\n",
    "print('data built!')\n",
    "\n",
    "# ------ start code ------\n",
    "# for loop\n",
    "\n",
    "for i in numbers:\n",
    "    if i % 2== 1:\n",
    "        print(i)\n",
    "\n",
    "\n",
    "\n",
    "# while loop\n",
    "\n",
    "i = 0\n",
    "while True:\n",
    "    if i >= len(numbers):\n",
    "        break\n",
    "    elif numbers[i] % 2 == 1:\n",
    "        print(numbers[i])\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "\n",
    "# ------ end code ------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 文件IO"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "python中的文件读写很简单，打开文件用open函数，写文件使用文件对象的write方法，不论是读还是写，首先都要先打开一个文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f = open('test', 'w') # 打开一个叫做的test的文件，w表示写入(write)\n",
    "f.write(\"test\") # 写入字符串\"test\"\n",
    "f.write(\"file\") # 写入字符串\"file\"\n",
    "f.write('\\n')   # 写入换行符\\n\n",
    "for i in range(10):\n",
    "    f.write(str(i) + '\\n') # 写入1到10\n",
    "f.close() # 关闭文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f = open('test', 'r') # 使用r读文件(read)\n",
    "text = f.read() # 使用read方法读文件\n",
    "f.close()\n",
    "print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f = open('test', 'r') # 使用r读文件(read)\n",
    "text = f.readline() # 使用readline方法读文件的一行\n",
    "f.close()\n",
    "print(text)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f = open('test', 'r') # 使用r读文件(read)\n",
    "text = f.readlines() # 使用readlines方法读文件的每一行，放到列表中，并返回\n",
    "f.close()\n",
    "print(text)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "以上是一种写文件的方式，三种读文件的方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "需要注意的是，如果在读取文件的过程中，或是在写文件的过程中出现bug，那么f.close()很有可能就不会被执行，这样会造成系统资源的浪费，而且可以打开的文件数量是有限的，所以一般我们使用try...finally来处理这个问题"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "try:\n",
    "    f = open('test', 'r')\n",
    "    text = f.readlines()\n",
    "    1 / 0\n",
    "finally:\n",
    "    if f:\n",
    "        f.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "用上面的这种写法，虽然会报错，但是文件确实是被关闭了，可以使用f.closed检查"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "f.closed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到f.closed为True，这说明文件已经被关闭了。但是上面的这种方法很不简洁，python提供了一个非常简单的写法"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('test', 'r') as f:\n",
    "    test = f.read()\n",
    "    print(test)\n",
    "    print(\"Is the file closed?\", f.closed)\n",
    "    1 / 0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(\"Is the file closed?\", f.closed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以看到，使用with open as f，同样可以做到读写文件，而且这样写起来很简洁，只要把打开文件后要执行的语句，使用4个空格作为缩进写在一起即可。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "值得注意的是，我们只使用了两种模式，r和w，事实上还有rb和wb，分别是读取二进制文件和写入二进制文件，当我们写程序，下载一些东西的时候，比如图片格式，常使用wb保存一个图片。  \n",
    "python还提供了一个模式“a”，这个模式是追加用的，如果用a模式打开文件，那么可以直接用write方法写入新的信息，这些信息会被追加到文件的尾部。以上这几种是很常用的模式。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "可以使用help(open)查看open的文档"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# test 1\n",
    "尝试使用**追加**模式，在test这个文件后面加入任何你想加的字符串，然后打印整个文件的内容"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "fooooo\n"
     ]
    }
   ],
   "source": [
    "# ------ start code ------\n",
    "\n",
    "with open('test', 'w+') as f:\n",
    "    f.write('fooooo')\n",
    "with open('test', 'r') as f:\n",
    "    print(f.read())\n",
    "\n",
    "# ------ end code ------"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用help(open)查看帮助文档"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function open in module io:\n",
      "\n",
      "open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)\n",
      "    Open file and return a stream.  Raise OSError upon failure.\n",
      "    \n",
      "    file is either a text or byte string giving the name (and the path\n",
      "    if the file isn't in the current working directory) of the file to\n",
      "    be opened or an integer file descriptor of the file to be\n",
      "    wrapped. (If a file descriptor is given, it is closed when the\n",
      "    returned I/O object is closed, unless closefd is set to False.)\n",
      "    \n",
      "    mode is an optional string that specifies the mode in which the file\n",
      "    is opened. It defaults to 'r' which means open for reading in text\n",
      "    mode.  Other common values are 'w' for writing (truncating the file if\n",
      "    it already exists), 'x' for creating and writing to a new file, and\n",
      "    'a' for appending (which on some Unix systems, means that all writes\n",
      "    append to the end of the file regardless of the current seek position).\n",
      "    In text mode, if encoding is not specified the encoding used is platform\n",
      "    dependent: locale.getpreferredencoding(False) is called to get the\n",
      "    current locale encoding. (For reading and writing raw bytes use binary\n",
      "    mode and leave encoding unspecified.) The available modes are:\n",
      "    \n",
      "    ========= ===============================================================\n",
      "    Character Meaning\n",
      "    --------- ---------------------------------------------------------------\n",
      "    'r'       open for reading (default)\n",
      "    'w'       open for writing, truncating the file first\n",
      "    'x'       create a new file and open it for writing\n",
      "    'a'       open for writing, appending to the end of the file if it exists\n",
      "    'b'       binary mode\n",
      "    't'       text mode (default)\n",
      "    '+'       open a disk file for updating (reading and writing)\n",
      "    'U'       universal newline mode (deprecated)\n",
      "    ========= ===============================================================\n",
      "    \n",
      "    The default mode is 'rt' (open for reading text). For binary random\n",
      "    access, the mode 'w+b' opens and truncates the file to 0 bytes, while\n",
      "    'r+b' opens the file without truncation. The 'x' mode implies 'w' and\n",
      "    raises an `FileExistsError` if the file already exists.\n",
      "    \n",
      "    Python distinguishes between files opened in binary and text modes,\n",
      "    even when the underlying operating system doesn't. Files opened in\n",
      "    binary mode (appending 'b' to the mode argument) return contents as\n",
      "    bytes objects without any decoding. In text mode (the default, or when\n",
      "    't' is appended to the mode argument), the contents of the file are\n",
      "    returned as strings, the bytes having been first decoded using a\n",
      "    platform-dependent encoding or using the specified encoding if given.\n",
      "    \n",
      "    'U' mode is deprecated and will raise an exception in future versions\n",
      "    of Python.  It has no effect in Python 3.  Use newline to control\n",
      "    universal newlines mode.\n",
      "    \n",
      "    buffering is an optional integer used to set the buffering policy.\n",
      "    Pass 0 to switch buffering off (only allowed in binary mode), 1 to select\n",
      "    line buffering (only usable in text mode), and an integer > 1 to indicate\n",
      "    the size of a fixed-size chunk buffer.  When no buffering argument is\n",
      "    given, the default buffering policy works as follows:\n",
      "    \n",
      "    * Binary files are buffered in fixed-size chunks; the size of the buffer\n",
      "      is chosen using a heuristic trying to determine the underlying device's\n",
      "      \"block size\" and falling back on `io.DEFAULT_BUFFER_SIZE`.\n",
      "      On many systems, the buffer will typically be 4096 or 8192 bytes long.\n",
      "    \n",
      "    * \"Interactive\" text files (files for which isatty() returns True)\n",
      "      use line buffering.  Other text files use the policy described above\n",
      "      for binary files.\n",
      "    \n",
      "    encoding is the name of the encoding used to decode or encode the\n",
      "    file. This should only be used in text mode. The default encoding is\n",
      "    platform dependent, but any encoding supported by Python can be\n",
      "    passed.  See the codecs module for the list of supported encodings.\n",
      "    \n",
      "    errors is an optional string that specifies how encoding errors are to\n",
      "    be handled---this argument should not be used in binary mode. Pass\n",
      "    'strict' to raise a ValueError exception if there is an encoding error\n",
      "    (the default of None has the same effect), or pass 'ignore' to ignore\n",
      "    errors. (Note that ignoring encoding errors can lead to data loss.)\n",
      "    See the documentation for codecs.register or run 'help(codecs.Codec)'\n",
      "    for a list of the permitted encoding error strings.\n",
      "    \n",
      "    newline controls how universal newlines works (it only applies to text\n",
      "    mode). It can be None, '', '\\n', '\\r', and '\\r\\n'.  It works as\n",
      "    follows:\n",
      "    \n",
      "    * On input, if newline is None, universal newlines mode is\n",
      "      enabled. Lines in the input can end in '\\n', '\\r', or '\\r\\n', and\n",
      "      these are translated into '\\n' before being returned to the\n",
      "      caller. If it is '', universal newline mode is enabled, but line\n",
      "      endings are returned to the caller untranslated. If it has any of\n",
      "      the other legal values, input lines are only terminated by the given\n",
      "      string, and the line ending is returned to the caller untranslated.\n",
      "    \n",
      "    * On output, if newline is None, any '\\n' characters written are\n",
      "      translated to the system default line separator, os.linesep. If\n",
      "      newline is '' or '\\n', no translation takes place. If newline is any\n",
      "      of the other legal values, any '\\n' characters written are translated\n",
      "      to the given string.\n",
      "    \n",
      "    If closefd is False, the underlying file descriptor will be kept open\n",
      "    when the file is closed. This does not work when a file name is given\n",
      "    and must be True in that case.\n",
      "    \n",
      "    A custom opener can be used by passing a callable as *opener*. The\n",
      "    underlying file descriptor for the file object is then obtained by\n",
      "    calling *opener* with (*file*, *flags*). *opener* must return an open\n",
      "    file descriptor (passing os.open as *opener* results in functionality\n",
      "    similar to passing None).\n",
      "    \n",
      "    open() returns a file object whose type depends on the mode, and\n",
      "    through which the standard file operations such as reading and writing\n",
      "    are performed. When open() is used to open a file in a text mode ('w',\n",
      "    'r', 'wt', 'rt', etc.), it returns a TextIOWrapper. When used to open\n",
      "    a file in a binary mode, the returned class varies: in read binary\n",
      "    mode, it returns a BufferedReader; in write binary and append binary\n",
      "    modes, it returns a BufferedWriter, and in read/write mode, it returns\n",
      "    a BufferedRandom.\n",
      "    \n",
      "    It is also possible to use a string or bytearray as a file for both\n",
      "    reading and writing. For strings StringIO can be used like a file\n",
      "    opened in a text mode, and for bytes a BytesIO can be used like a file\n",
      "    opened in a binary mode.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(open)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
